package algorithms

import (
	"context"
	"fmt"
	"io/fs"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"sort"
	"strings"
	"sync"
	"time"
)

// ToolSystem 工具调用系统
type ToolSystem struct {
	tools       map[string]Tool
	mu          sync.RWMutex
	ctx         context.Context
	cancel      context.CancelFunc
	executor    *ToolExecutor
	validator   *ToolValidator
	semanticIdx *SemanticIndex
}

// Tool 工具接口
type Tool interface {
	Name() string
	Description() string
	Parameters() map[string]interface{}
	Execute(ctx context.Context, params map[string]interface{}) (*ToolResult, error)
	Validate(params map[string]interface{}) error
}

// ToolResult 工具执行结果
type ToolResult struct {
	Success   bool                   `json:"success"`
	Data      interface{}            `json:"data,omitempty"`
	Error     string                 `json:"error,omitempty"`
	Metadata  map[string]interface{} `json:"metadata,omitempty"`
	Duration  time.Duration          `json:"duration"`
	Timestamp time.Time              `json:"timestamp"`
}

// ToolExecutor 工具执行器
type ToolExecutor struct {
	timeout     time.Duration
	maxRetries  int
	workerPool  *WorkerPool
	resultCache *LRUCache
}

// ToolValidator 工具验证器
type ToolValidator struct {
	schemas map[string]interface{}
}

// SemanticIndex 语义索引
type SemanticIndex struct {
	index     map[string][]string
	embedding map[string][]float64
	mu        sync.RWMutex
}

// NewToolSystem 创建工具系统
func NewToolSystem() *ToolSystem {
	ctx, cancel := context.WithCancel(context.Background())
	
	ts := &ToolSystem{
		tools:  make(map[string]Tool),
		ctx:    ctx,
		cancel: cancel,
		executor: &ToolExecutor{
			timeout:     30 * time.Second,
			maxRetries:  3,
			workerPool:  NewWorkerPool(4, 100),
			resultCache: NewLRUCache(100),
		},
		validator: &ToolValidator{
			schemas: make(map[string]interface{}),
		},
		semanticIdx: &SemanticIndex{
			index:     make(map[string][]string),
			embedding: make(map[string][]float64),
		},
	}

	// 注册内置工具
	ts.registerBuiltinTools()
	
	return ts
}

// RegisterTool 注册工具
func (ts *ToolSystem) RegisterTool(tool Tool) error {
	ts.mu.Lock()
	defer ts.mu.Unlock()

	name := tool.Name()
	if _, exists := ts.tools[name]; exists {
		return fmt.Errorf("tool %s already registered", name)
	}

	// 验证工具
	if err := ts.validateTool(tool); err != nil {
		return fmt.Errorf("tool validation failed: %w", err)
	}

	ts.tools[name] = tool
	
	// 更新语义索引
	ts.updateSemanticIndex(tool)
	
	return nil
}

// ExecuteTool 执行工具
func (ts *ToolSystem) ExecuteTool(name string, params map[string]interface{}) (*ToolResult, error) {
	ts.mu.RLock()
	tool, exists := ts.tools[name]
	ts.mu.RUnlock()

	if !exists {
		return nil, fmt.Errorf("tool %s not found", name)
	}

	// 验证参数
	if err := tool.Validate(params); err != nil {
		return &ToolResult{
			Success:   false,
			Error:     fmt.Sprintf("parameter validation failed: %v", err),
			Timestamp: time.Now(),
		}, nil
	}

	// 检查缓存
	cacheKey := fmt.Sprintf("%s_%v", name, params)
	if cached, found := ts.executor.resultCache.Get(cacheKey); found {
		if result, ok := cached.(*ToolResult); ok {
			return result, nil
		}
	}

	// 执行工具
	start := time.Now()
	ctx, cancel := context.WithTimeout(ts.ctx, ts.executor.timeout)
	defer cancel()

	result, err := tool.Execute(ctx, params)
	if err != nil {
		return &ToolResult{
			Success:   false,
			Error:     err.Error(),
			Duration:  time.Since(start),
			Timestamp: time.Now(),
		}, nil
	}

	result.Duration = time.Since(start)
	result.Timestamp = time.Now()

	// 缓存结果
	ts.executor.resultCache.Put(cacheKey, result, 10*time.Minute)

	return result, nil
}

// SearchTools 搜索工具
func (ts *ToolSystem) SearchTools(query string) []string {
	ts.mu.RLock()
	defer ts.mu.RUnlock()

	var matches []string
	query = strings.ToLower(query)

	for name, tool := range ts.tools {
		// 名称匹配
		if strings.Contains(strings.ToLower(name), query) {
			matches = append(matches, name)
			continue
		}

		// 描述匹配
		if strings.Contains(strings.ToLower(tool.Description()), query) {
			matches = append(matches, name)
		}
	}

	// 语义搜索
	semanticMatches := ts.semanticSearch(query)
	for _, match := range semanticMatches {
		if !contains(matches, match) {
			matches = append(matches, match)
		}
	}

	return matches
}

// ListTools 列出所有工具
func (ts *ToolSystem) ListTools() []string {
	ts.mu.RLock()
	defer ts.mu.RUnlock()

	var names []string
	for name := range ts.tools {
		names = append(names, name)
	}

	sort.Strings(names)
	return names
}

// GetToolInfo 获取工具信息
func (ts *ToolSystem) GetToolInfo(name string) (Tool, bool) {
	ts.mu.RLock()
	defer ts.mu.RUnlock()

	tool, exists := ts.tools[name]
	return tool, exists
}

// Stop 停止工具系统
func (ts *ToolSystem) Stop() {
	ts.cancel()
	ts.executor.workerPool.Stop()
}

// registerBuiltinTools 注册内置工具
func (ts *ToolSystem) registerBuiltinTools() {
	// 文件操作工具
	ts.RegisterTool(&FileReadTool{})
	ts.RegisterTool(&FileWriteTool{})
	ts.RegisterTool(&FileListTool{})
	ts.RegisterTool(&FileSearchTool{})
	ts.RegisterTool(&FileDeleteTool{})

	// 命令执行工具
	ts.RegisterTool(&CommandExecuteTool{})
	ts.RegisterTool(&ProcessListTool{})

	// 系统信息工具
	ts.RegisterTool(&SystemInfoTool{})
	ts.RegisterTool(&EnvironmentTool{})

	// 网络工具
	ts.RegisterTool(&HTTPRequestTool{})
	ts.RegisterTool(&PingTool{})

	// 文本处理工具
	ts.RegisterTool(&RegexTool{})
	ts.RegisterTool(&JSONTool{})
	ts.RegisterTool(&Base64Tool{})
}

// validateTool 验证工具
func (ts *ToolSystem) validateTool(tool Tool) error {
	if tool.Name() == "" {
		return fmt.Errorf("tool name cannot be empty")
	}

	if tool.Description() == "" {
		return fmt.Errorf("tool description cannot be empty")
	}

	return nil
}

// updateSemanticIndex 更新语义索引
func (ts *ToolSystem) updateSemanticIndex(tool Tool) {
	ts.semanticIdx.mu.Lock()
	defer ts.semanticIdx.mu.Unlock()

	name := tool.Name()
	desc := tool.Description()

	// 简单的关键词提取
	keywords := extractKeywords(desc)
	ts.semanticIdx.index[name] = keywords
}

// semanticSearch 语义搜索
func (ts *ToolSystem) semanticSearch(query string) []string {
	ts.semanticIdx.mu.RLock()
	defer ts.semanticIdx.mu.RUnlock()

	var matches []string
	queryKeywords := extractKeywords(query)

	for toolName, keywords := range ts.semanticIdx.index {
		score := calculateSimilarity(queryKeywords, keywords)
		if score > 0.3 { // 相似度阈值
			matches = append(matches, toolName)
		}
	}

	return matches
}

// extractKeywords 提取关键词
func extractKeywords(text string) []string {
	// 简单的关键词提取：分词并过滤停用词
	words := strings.Fields(strings.ToLower(text))
	stopWords := map[string]bool{
		"the": true, "a": true, "an": true, "and": true, "or": true,
		"but": true, "in": true, "on": true, "at": true, "to": true,
		"for": true, "of": true, "with": true, "by": true, "is": true,
		"are": true, "was": true, "were": true, "be": true, "been": true,
	}

	var keywords []string
	for _, word := range words {
		word = strings.Trim(word, ".,!?;:()[]{}\"'")
		if len(word) > 2 && !stopWords[word] {
			keywords = append(keywords, word)
		}
	}

	return keywords
}

// calculateSimilarity 计算相似度
func calculateSimilarity(keywords1, keywords2 []string) float64 {
	if len(keywords1) == 0 || len(keywords2) == 0 {
		return 0
	}

	set1 := make(map[string]bool)
	for _, word := range keywords1 {
		set1[word] = true
	}

	common := 0
	for _, word := range keywords2 {
		if set1[word] {
			common++
		}
	}

	// Jaccard相似度
	union := len(keywords1) + len(keywords2) - common
	if union == 0 {
		return 0
	}

	return float64(common) / float64(union)
}

// contains 检查切片是否包含元素
func contains(slice []string, item string) bool {
	for _, s := range slice {
		if s == item {
			return true
		}
	}
	return false
}

// =============================================================================
// 内置工具实现
// =============================================================================

// FileReadTool 文件读取工具
type FileReadTool struct{}

func (t *FileReadTool) Name() string {
	return "file_read"
}

func (t *FileReadTool) Description() string {
	return "Read content from a file"
}

func (t *FileReadTool) Parameters() map[string]interface{} {
	return map[string]interface{}{
		"path": map[string]interface{}{
			"type":        "string",
			"description": "File path to read",
			"required":    true,
		},
		"encoding": map[string]interface{}{
			"type":        "string",
			"description": "File encoding (utf-8, gbk, etc.)",
			"default":     "utf-8",
		},
	}
}

func (t *FileReadTool) Validate(params map[string]interface{}) error {
	path, ok := params["path"].(string)
	if !ok || path == "" {
		return fmt.Errorf("path parameter is required and must be a string")
	}
	return nil
}

func (t *FileReadTool) Execute(ctx context.Context, params map[string]interface{}) (*ToolResult, error) {
	path := params["path"].(string)

	content, err := os.ReadFile(path)
	if err != nil {
		return nil, fmt.Errorf("failed to read file: %w", err)
	}

	return &ToolResult{
		Success: true,
		Data:    string(content),
		Metadata: map[string]interface{}{
			"size": len(content),
			"path": path,
		},
	}, nil
}

// FileWriteTool 文件写入工具
type FileWriteTool struct{}

func (t *FileWriteTool) Name() string {
	return "file_write"
}

func (t *FileWriteTool) Description() string {
	return "Write content to a file"
}

func (t *FileWriteTool) Parameters() map[string]interface{} {
	return map[string]interface{}{
		"path": map[string]interface{}{
			"type":        "string",
			"description": "File path to write",
			"required":    true,
		},
		"content": map[string]interface{}{
			"type":        "string",
			"description": "Content to write",
			"required":    true,
		},
		"append": map[string]interface{}{
			"type":        "boolean",
			"description": "Append to file instead of overwriting",
			"default":     false,
		},
	}
}

func (t *FileWriteTool) Validate(params map[string]interface{}) error {
	path, ok := params["path"].(string)
	if !ok || path == "" {
		return fmt.Errorf("path parameter is required and must be a string")
	}

	content, ok := params["content"].(string)
	if !ok {
		return fmt.Errorf("content parameter is required and must be a string")
	}

	_ = content // 避免未使用变量警告
	return nil
}

func (t *FileWriteTool) Execute(ctx context.Context, params map[string]interface{}) (*ToolResult, error) {
	path := params["path"].(string)
	content := params["content"].(string)
	append := false
	if a, ok := params["append"].(bool); ok {
		append = a
	}

	var err error
	if append {
		file, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
		if err != nil {
			return nil, fmt.Errorf("failed to open file for append: %w", err)
		}
		defer file.Close()
		_, err = file.WriteString(content)
	} else {
		err = os.WriteFile(path, []byte(content), 0644)
	}

	if err != nil {
		return nil, fmt.Errorf("failed to write file: %w", err)
	}

	return &ToolResult{
		Success: true,
		Data:    "File written successfully",
		Metadata: map[string]interface{}{
			"path":   path,
			"size":   len(content),
			"append": append,
		},
	}, nil
}

// FileListTool 文件列表工具
type FileListTool struct{}

func (t *FileListTool) Name() string {
	return "file_list"
}

func (t *FileListTool) Description() string {
	return "List files and directories in a path"
}

func (t *FileListTool) Parameters() map[string]interface{} {
	return map[string]interface{}{
		"path": map[string]interface{}{
			"type":        "string",
			"description": "Directory path to list",
			"default":     ".",
		},
		"recursive": map[string]interface{}{
			"type":        "boolean",
			"description": "List files recursively",
			"default":     false,
		},
		"pattern": map[string]interface{}{
			"type":        "string",
			"description": "File pattern to match (glob)",
		},
	}
}

func (t *FileListTool) Validate(params map[string]interface{}) error {
	return nil // 所有参数都是可选的
}

func (t *FileListTool) Execute(ctx context.Context, params map[string]interface{}) (*ToolResult, error) {
	path := "."
	if p, ok := params["path"].(string); ok && p != "" {
		path = p
	}

	recursive := false
	if r, ok := params["recursive"].(bool); ok {
		recursive = r
	}

	pattern := ""
	if p, ok := params["pattern"].(string); ok {
		pattern = p
	}

	var files []map[string]interface{}

	if recursive {
		err := filepath.WalkDir(path, func(filePath string, d fs.DirEntry, err error) error {
			if err != nil {
				return err
			}

			if pattern != "" {
				matched, _ := filepath.Match(pattern, d.Name())
				if !matched {
					return nil
				}
			}

			info, err := d.Info()
			if err != nil {
				return err
			}

			files = append(files, map[string]interface{}{
				"name":    d.Name(),
				"path":    filePath,
				"size":    info.Size(),
				"mode":    info.Mode().String(),
				"modTime": info.ModTime(),
				"isDir":   d.IsDir(),
			})

			return nil
		})

		if err != nil {
			return nil, fmt.Errorf("failed to walk directory: %w", err)
		}
	} else {
		entries, err := os.ReadDir(path)
		if err != nil {
			return nil, fmt.Errorf("failed to read directory: %w", err)
		}

		for _, entry := range entries {
			if pattern != "" {
				matched, _ := filepath.Match(pattern, entry.Name())
				if !matched {
					continue
				}
			}

			info, err := entry.Info()
			if err != nil {
				continue
			}

			files = append(files, map[string]interface{}{
				"name":    entry.Name(),
				"path":    filepath.Join(path, entry.Name()),
				"size":    info.Size(),
				"mode":    info.Mode().String(),
				"modTime": info.ModTime(),
				"isDir":   entry.IsDir(),
			})
		}
	}

	return &ToolResult{
		Success: true,
		Data:    files,
		Metadata: map[string]interface{}{
			"path":      path,
			"count":     len(files),
			"recursive": recursive,
			"pattern":   pattern,
		},
	}, nil
}

// CommandExecuteTool 命令执行工具
type CommandExecuteTool struct{}

func (t *CommandExecuteTool) Name() string {
	return "command_execute"
}

func (t *CommandExecuteTool) Description() string {
	return "Execute system commands"
}

func (t *CommandExecuteTool) Parameters() map[string]interface{} {
	return map[string]interface{}{
		"command": map[string]interface{}{
			"type":        "string",
			"description": "Command to execute",
			"required":    true,
		},
		"args": map[string]interface{}{
			"type":        "array",
			"description": "Command arguments",
		},
		"workdir": map[string]interface{}{
			"type":        "string",
			"description": "Working directory",
		},
		"timeout": map[string]interface{}{
			"type":        "integer",
			"description": "Timeout in seconds",
			"default":     30,
		},
	}
}

func (t *CommandExecuteTool) Validate(params map[string]interface{}) error {
	command, ok := params["command"].(string)
	if !ok || command == "" {
		return fmt.Errorf("command parameter is required and must be a string")
	}
	return nil
}

func (t *CommandExecuteTool) Execute(ctx context.Context, params map[string]interface{}) (*ToolResult, error) {
	command := params["command"].(string)

	var args []string
	if a, ok := params["args"].([]interface{}); ok {
		for _, arg := range a {
			if s, ok := arg.(string); ok {
				args = append(args, s)
			}
		}
	}

	timeout := 30
	if t, ok := params["timeout"].(int); ok {
		timeout = t
	}

	ctx, cancel := context.WithTimeout(ctx, time.Duration(timeout)*time.Second)
	defer cancel()

	cmd := exec.CommandContext(ctx, command, args...)

	if workdir, ok := params["workdir"].(string); ok && workdir != "" {
		cmd.Dir = workdir
	}

	output, err := cmd.CombinedOutput()
	if err != nil {
		return &ToolResult{
			Success: false,
			Error:   fmt.Sprintf("command failed: %v", err),
			Data:    string(output),
		}, nil
	}

	return &ToolResult{
		Success: true,
		Data:    string(output),
		Metadata: map[string]interface{}{
			"command": command,
			"args":    args,
			"exitCode": cmd.ProcessState.ExitCode(),
		},
	}, nil
}

// RegexTool 正则表达式工具
type RegexTool struct{}

func (t *RegexTool) Name() string {
	return "regex"
}

func (t *RegexTool) Description() string {
	return "Perform regular expression operations"
}

func (t *RegexTool) Parameters() map[string]interface{} {
	return map[string]interface{}{
		"pattern": map[string]interface{}{
			"type":        "string",
			"description": "Regular expression pattern",
			"required":    true,
		},
		"text": map[string]interface{}{
			"type":        "string",
			"description": "Text to search in",
			"required":    true,
		},
		"operation": map[string]interface{}{
			"type":        "string",
			"description": "Operation: match, find, replace",
			"default":     "find",
		},
		"replacement": map[string]interface{}{
			"type":        "string",
			"description": "Replacement text (for replace operation)",
		},
	}
}

func (t *RegexTool) Validate(params map[string]interface{}) error {
	pattern, ok := params["pattern"].(string)
	if !ok || pattern == "" {
		return fmt.Errorf("pattern parameter is required")
	}

	text, ok := params["text"].(string)
	if !ok {
		return fmt.Errorf("text parameter is required")
	}

	_, err := regexp.Compile(pattern)
	if err != nil {
		return fmt.Errorf("invalid regex pattern: %w", err)
	}

	_ = text // 避免未使用变量警告
	return nil
}

func (t *RegexTool) Execute(ctx context.Context, params map[string]interface{}) (*ToolResult, error) {
	pattern := params["pattern"].(string)
	text := params["text"].(string)
	operation := "find"
	if op, ok := params["operation"].(string); ok {
		operation = op
	}

	re, err := regexp.Compile(pattern)
	if err != nil {
		return nil, fmt.Errorf("failed to compile regex: %w", err)
	}

	var result interface{}
	switch operation {
	case "match":
		result = re.MatchString(text)
	case "find":
		result = re.FindAllString(text, -1)
	case "replace":
		replacement := ""
		if r, ok := params["replacement"].(string); ok {
			replacement = r
		}
		result = re.ReplaceAllString(text, replacement)
	default:
		return nil, fmt.Errorf("unsupported operation: %s", operation)
	}

	return &ToolResult{
		Success: true,
		Data:    result,
		Metadata: map[string]interface{}{
			"pattern":   pattern,
			"operation": operation,
		},
	}, nil
}

// 其他工具的简化实现...

// FileSearchTool 文件搜索工具
type FileSearchTool struct{}

func (t *FileSearchTool) Name() string { return "file_search" }
func (t *FileSearchTool) Description() string { return "Search for text in files" }
func (t *FileSearchTool) Parameters() map[string]interface{} { return map[string]interface{}{} }
func (t *FileSearchTool) Validate(params map[string]interface{}) error { return nil }
func (t *FileSearchTool) Execute(ctx context.Context, params map[string]interface{}) (*ToolResult, error) {
	return &ToolResult{Success: true, Data: "Search functionality not implemented yet"}, nil
}

// FileDeleteTool 文件删除工具
type FileDeleteTool struct{}

func (t *FileDeleteTool) Name() string { return "file_delete" }
func (t *FileDeleteTool) Description() string { return "Delete files or directories" }
func (t *FileDeleteTool) Parameters() map[string]interface{} { return map[string]interface{}{} }
func (t *FileDeleteTool) Validate(params map[string]interface{}) error { return nil }
func (t *FileDeleteTool) Execute(ctx context.Context, params map[string]interface{}) (*ToolResult, error) {
	return &ToolResult{Success: true, Data: "Delete functionality not implemented yet"}, nil
}

// ProcessListTool 进程列表工具
type ProcessListTool struct{}

func (t *ProcessListTool) Name() string { return "process_list" }
func (t *ProcessListTool) Description() string { return "List running processes" }
func (t *ProcessListTool) Parameters() map[string]interface{} { return map[string]interface{}{} }
func (t *ProcessListTool) Validate(params map[string]interface{}) error { return nil }
func (t *ProcessListTool) Execute(ctx context.Context, params map[string]interface{}) (*ToolResult, error) {
	return &ToolResult{Success: true, Data: "Process list functionality not implemented yet"}, nil
}

// SystemInfoTool 系统信息工具
type SystemInfoTool struct{}

func (t *SystemInfoTool) Name() string { return "system_info" }
func (t *SystemInfoTool) Description() string { return "Get system information" }
func (t *SystemInfoTool) Parameters() map[string]interface{} { return map[string]interface{}{} }
func (t *SystemInfoTool) Validate(params map[string]interface{}) error { return nil }
func (t *SystemInfoTool) Execute(ctx context.Context, params map[string]interface{}) (*ToolResult, error) {
	return &ToolResult{Success: true, Data: "System info functionality not implemented yet"}, nil
}

// EnvironmentTool 环境变量工具
type EnvironmentTool struct{}

func (t *EnvironmentTool) Name() string { return "environment" }
func (t *EnvironmentTool) Description() string { return "Get or set environment variables" }
func (t *EnvironmentTool) Parameters() map[string]interface{} { return map[string]interface{}{} }
func (t *EnvironmentTool) Validate(params map[string]interface{}) error { return nil }
func (t *EnvironmentTool) Execute(ctx context.Context, params map[string]interface{}) (*ToolResult, error) {
	return &ToolResult{Success: true, Data: "Environment functionality not implemented yet"}, nil
}

// HTTPRequestTool HTTP请求工具
type HTTPRequestTool struct{}

func (t *HTTPRequestTool) Name() string { return "http_request" }
func (t *HTTPRequestTool) Description() string { return "Make HTTP requests" }
func (t *HTTPRequestTool) Parameters() map[string]interface{} { return map[string]interface{}{} }
func (t *HTTPRequestTool) Validate(params map[string]interface{}) error { return nil }
func (t *HTTPRequestTool) Execute(ctx context.Context, params map[string]interface{}) (*ToolResult, error) {
	return &ToolResult{Success: true, Data: "HTTP request functionality not implemented yet"}, nil
}

// PingTool Ping工具
type PingTool struct{}

func (t *PingTool) Name() string { return "ping" }
func (t *PingTool) Description() string { return "Ping network hosts" }
func (t *PingTool) Parameters() map[string]interface{} { return map[string]interface{}{} }
func (t *PingTool) Validate(params map[string]interface{}) error { return nil }
func (t *PingTool) Execute(ctx context.Context, params map[string]interface{}) (*ToolResult, error) {
	return &ToolResult{Success: true, Data: "Ping functionality not implemented yet"}, nil
}

// JSONTool JSON处理工具
type JSONTool struct{}

func (t *JSONTool) Name() string { return "json" }
func (t *JSONTool) Description() string { return "Parse and manipulate JSON data" }
func (t *JSONTool) Parameters() map[string]interface{} { return map[string]interface{}{} }
func (t *JSONTool) Validate(params map[string]interface{}) error { return nil }
func (t *JSONTool) Execute(ctx context.Context, params map[string]interface{}) (*ToolResult, error) {
	return &ToolResult{Success: true, Data: "JSON functionality not implemented yet"}, nil
}

// Base64Tool Base64编码工具
type Base64Tool struct{}

func (t *Base64Tool) Name() string { return "base64" }
func (t *Base64Tool) Description() string { return "Encode and decode Base64 data" }
func (t *Base64Tool) Parameters() map[string]interface{} { return map[string]interface{}{} }
func (t *Base64Tool) Validate(params map[string]interface{}) error { return nil }
func (t *Base64Tool) Execute(ctx context.Context, params map[string]interface{}) (*ToolResult, error) {
	return &ToolResult{Success: true, Data: "Base64 functionality not implemented yet"}, nil
}